package com.gwtprocessingjs.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

/** 
 * This class demonstrates pushing data from Processing code
 * written in Javascript into GWT.
 */
public class JsToGwt implements EntryPoint {
	
	// UI Elements.
	private final FlowPanel back = new FlowPanel();
	private final Label positionHeader = new Label("The position of the ball is: ");
	
	// Note that this label is static, to go along with the static method to
	// update its text.
	private static final Label positionLabel = new Label("x y");
	
	@Override
	public void onModuleLoad() {
		
		// Note: methods used by the Javascript must be exported
		// before the canvas is initialized or the processing rendering
		// loop may crash as it attempts to access missing methods.
		exportUpdatePositionMethod();
		initializeCanvas();
		
		back.add(new Label("Pushing data from Processing JS to GWT"));	
		HorizontalPanel hp = new HorizontalPanel();
		hp.add(positionHeader);
		hp.add(positionLabel);
		back.add(hp);
		RootPanel.get("gwt").add(back);
	}
	
	/**
	 * This method will get exported to a variable name that can be
	 * accessed from the JS file.
	 *
	 * @param positionText new position text
	 */
	public static void updatePosition(String positionText) {
		positionLabel.setText(positionText);
	}
	
	// --- Private Methods ---
	
	/**
	 * Initialize a Processing isntance and associate it with the
	 * Canvas element defined statically in the HTML file.
	 */
	private native void initializeCanvas() /*-{
		$wnd.initializeCanvas();
	}-*/;
	
	/**
	 * Calling GWT methods from straight JS requires special syntax and handling by the
	 * GWT compiler. Since the javascript code is in an external js file, GWT can't
	 * generate the glue, so the way to make those calls is by statically exporting
	 * the function name to a variable which can be accessed in the JS.
	 *
	 * <p>http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html
	 */
	private native void exportUpdatePositionMethod() /*-{
		
		// Bind the static updatePosition method on this class to
		// a variable in $wnd named "updatePosition"
		$wnd.updatePosition =
          $entry(@com.gwtprocessingjs.client.JsToGwt::updatePosition(Ljava/lang/String;));
	}-*/;
}
